package com.kingyun.gpsinspection.purificationservice.services.tdm.innerservice.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqhilink.api.common.utils.UniqueUtil;
import com.kingyun.gpsinspection.purificationservice.common.activiti.ActivitiConstants;
import com.kingyun.gpsinspection.purificationservice.common.utils.FileTypeUtil;
import com.kingyun.gpsinspection.purificationservice.dao.mapper.iam.accessory.OrganizationMapper;
import com.kingyun.gpsinspection.purificationservice.dao.mapper.som.WorkOrderMapper;
import com.kingyun.gpsinspection.purificationservice.dao.mapper.tdm.*;
import com.kingyun.gpsinspection.purificationservice.facade.model.File;
import com.kingyun.gpsinspection.purificationservice.facade.model.activiti.HistoricNode;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.Employee;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.EmployeeVo;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.EntityVo;
import com.kingyun.gpsinspection.purificationservice.facade.model.jsm.Organization;
import com.kingyun.gpsinspection.purificationservice.facade.model.som.User;
import com.kingyun.gpsinspection.purificationservice.facade.model.tdm.CustomWorkCriteria;
import com.kingyun.gpsinspection.purificationservice.facade.model.tdm.Problem;
import com.kingyun.gpsinspection.purificationservice.facade.model.tdm.WorkOrderEmployee;
import com.kingyun.gpsinspection.purificationservice.facade.model.tdm.WorkOrderVo;
import com.kingyun.gpsinspection.purificationservice.facade.service.activiti.base.WorkFlowService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.OutEntityService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.OutOrganizationService;
import com.kingyun.gpsinspection.purificationservice.facade.service.jsm.employee.JsmEmployeeService;
import com.kingyun.gpsinspection.purificationservice.facade.service.tdm.NewProblemService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by jiangjx on 2017/6/10.
 */
public class NewProblemServiceImpl implements NewProblemService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public static final String PROBLEM_FLOW_KEY = "problem";
    @Autowired
    private TdmProblemMapper tdmProblemMapper;
    @Autowired
    private OutEntityService outEntityService;
    @Autowired
    public OutOrganizationService outOrganizationService;
    @Autowired
    private TdmFileMapper tdmFileMapper;
    @Autowired
    private WorkFlowService workFlowService;
    @Autowired
    private TdmWorkOrderMapper tdmWorkOrderMapper;
    @Autowired
    private WorkOrderEmployeeMapper workOrderEmployeeMapper;
    @Autowired
    private OrganizationMapper organizationMapper;
    @Autowired
    private JsmEmployeeService jsmEmployeeService;
    @Autowired
    private WorkOrderMapper workOrderMapper;
    @Autowired
    private CustomWorkCriteriaMapper customWorkCriteriaMapper;

    /**
     * 发起问题流程
     *
     * @param employeeVo   当前登录人信息
     * @param problem      问题信息
     * @param uploadFiles  上传附件
     * @param deletedFiles 删除附件
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int save(EmployeeVo employeeVo, Problem problem, String uploadFiles, String deletedFiles) {
        //设置问题所属组织
        setOrgIdByCondition(employeeVo, problem);
        problem.setProblemId(UniqueUtil.uuid());
        //设置创建时间
        problem.setCreateTime(new Date());
        //设置修改时间
        problem.setModifyTime(new Date());
        //更新问题状态
        problem.setStatus((short) 0);
        problem.setCreateUserId(employeeVo.getEmployeeId());
        problem.setModifyUserId(employeeVo.getEmployeeId());
        problem.setIsDelete((short) 0);
        //保存问题
        tdmProblemMapper.insert(problem);

        if (StringUtils.isNotBlank(uploadFiles)) {
            //强制转换成集合
            List<File> listFiles = JSON.parseArray(uploadFiles, File.class);
            //重新设置附件属性
            for (int i = 0; i < listFiles.size(); i++) {
                File _file = listFiles.get(i);
                //设置主键
                _file.setFileId(UniqueUtil.uuid());
                //设置业务数据id
                _file.setBusinessId(problem.getProblemId());
                _file.setFileType((short) FileTypeUtil.getFileTypeByFileName(_file.getFileName()));
            }

            //必须判断非空
            if (listFiles != null && listFiles.size() > 0) {
                tdmFileMapper.insertByList(listFiles);
            }
        }

        //需要删除的附件信息
        if (StringUtils.isNotBlank(deletedFiles)) {
            //强制转换成集合
            List<File> listFiles = JSON.parseArray(deletedFiles, File.class);
            if (listFiles != null && listFiles.size() > 0) {
                int len = listFiles.size();
                for (int i = 0; i < len; i++) {
                    File _file = listFiles.get(i);
                    tdmFileMapper.deleteByPrimaryKey(_file.getFileId());
                }
            }
        }
        //开启流程
        try {
            workFlowService.startProcessInstanceByKey(PROBLEM_FLOW_KEY, problem.getProblemId(), null, employeeVo.getEmployeeId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 设置问题对象组织
     *
     * @param employeeVo
     * @param problem
     */
    public void setOrgIdByCondition(EmployeeVo employeeVo, Problem problem) {
        //设置问题所属组织
        if (StringUtils.isNotBlank(problem.getProblemObject())) {
            try {
                EntityVo entityVo = outEntityService.getEntityByEntityId(problem.getProblemObject());
                //问题对象ID是生产实体
                if (entityVo != null) {
                    problem.setOrgId(entityVo.getParentOrgId());
                }
                //问题对象ID不是生产实体，而是组织ID
                Organization organization = outOrganizationService.queryOrganization(problem.getProblemObject());
                if (organization != null) {
                    problem.setOrgId(problem.getProblemObject());
                }
                if (entityVo == null && organization == null) {
                    problem.setOrgId(employeeVo.getOrgId());
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        } else {
            problem.setOrgId(employeeVo.getOrgId());
        }
    }

    /**
     * 审批流程
     *
     * @param radioVal        流程变量
     * @param approvalOpinion 审批意见
     * @param employeeVo      登录人信息
     * @param workOrderList   工单list
     * @param problemId       问题id
     * @param taskId          任务id
     */
    @Override
    public int approvalStep(EmployeeVo employeeVo, String radioVal, String approvalOpinion, List<WorkOrderVo> workOrderList, String problemId, String taskId, String nodeName) {
        int a = 0;
        if (radioVal.equals("3")) {
            // 将流程走向下一步
            Map<String, Object> variable = new HashMap<>();
            variable.put("cond1", radioVal);
            Map<String, Object> map = workFlowService.completeTask(taskId, variable, approvalOpinion, employeeVo.getEmployeeId());
            if (map.get("state").toString().equals("false")) {
                new Exception(map.get("msg").toString());
            }
            return a;
        } else if (radioVal.equals("4") && nodeName.contains("维修工段处理")) {
            // 将流程走向下一步
            Map<String, Object> variable = new HashMap<>();
            variable.put("cond2", 1);
            Map<String, Object> map = workFlowService.completeTask(taskId, variable, approvalOpinion, employeeVo.getEmployeeId());
            if (map.get("state").toString().equals("false")) {
                new Exception(map.get("msg").toString());
            }
            return a;
        } else if (radioVal.equals("4")) {
            //修改问题状态
            Problem problem = new Problem();
            problem.setProblemId(problemId);
            problem.setStatus(new Short("3"));
            tdmProblemMapper.updateByPrimaryKeySelective(problem);
            // 将流程走向下一步
            Map<String, Object> variable = new HashMap<>();
            variable.put("cond1", radioVal);
            Map<String, Object> map = workFlowService.completeTask(taskId, variable, approvalOpinion, employeeVo.getEmployeeId());
            if (map.get("state").toString().equals("false")) {
                new Exception(map.get("msg").toString());
            }
            return a;
        }
        //修改问题状态
        Problem problem = new Problem();
        problem.setProblemId(problemId);
        problem.setStatus(new Short("1"));
        tdmProblemMapper.updateByPrimaryKeySelective(problem);
        //创建工单
        saveWorkOrderList(employeeVo, problemId, workOrderList);
        //将流程变量装进MAP中
        Map<String, Object> variable = new HashMap<>();
        if (null != nodeName && nodeName.contains("维修工段处理")) {
            variable.put("cond2", radioVal);
        } else {
            variable.put("cond1", radioVal);
        }
        variable.put(ActivitiConstants.MANUAL_PERSON, achievePersons(workOrderList));
        // 将流程走向下一步
        Map<String, Object> map = workFlowService.completeTask(taskId, variable, approvalOpinion, employeeVo.getEmployeeId());
        if (map.get("state").toString().equals("false")) {
            new Exception(map.get("msg").toString());
        }
        return a;
    }

    @Override
    public int solveStep(EmployeeVo employeeVo, String solveVal, String solveOpinion, String problemId, String taskId, String ids, String nodeName) {
        int a = 0;
        if (solveVal.equals("2")) {//验收通过
            finishProblem(problemId, taskId, employeeVo, solveOpinion, solveVal, nodeName);
        } else if (solveVal.equals("1")) {//验收不通过
            noPass(problemId, taskId, employeeVo, solveOpinion, solveVal, ids, nodeName);
        }
        return a;
    }


    /**
     * 验收不通过
     */
    private void noPass(String problemId, String taskId, EmployeeVo employeeVo, String solveOpinion, String solveVal, String ids, String nodeName) {
        //重新下发工单
        List<String> idList = new ArrayList<>();
        for (String id : ids.split(",")) {
            idList.add(id);
        }
        List<WorkOrderVo> workOrders = workOrderMapper.queryWorkOrderByIds(idList);
        //创建工单
        saveWorkOrderList(employeeVo, problemId, workOrders);
        //修改问题状态
        Problem problem = new Problem();
        problem.setProblemId(problemId);
        problem.setStatus(new Short("1"));
        tdmProblemMapper.updateByPrimaryKeySelective(problem);
        //将流程变量装进MAP中
        Map<String, Object> variable = new HashMap<>();
        variable.put(getKey(nodeName), solveVal);
        variable.put(ActivitiConstants.MANUAL_PERSON, achievePersons(workOrders));
        // 将流程走向下一步
        Map<String, Object> map = workFlowService.completeTask(taskId, variable, solveOpinion, employeeVo.getEmployeeId());
        if (map.get("state").toString().equals("false")) {
            new Exception(map.get("msg").toString());
        }
    }

    /**
     * 根据节点走决定流程变量
     */
    private String getKey(String nodeName) {
        if (nodeName.contains("净化工段验收")) {
            return "cond3";
        } else if (nodeName.contains("维修工段验收")) {
            return "cond4";
        } else if (nodeName.contains("联合验收")) {
            return "cond5";
        }
        return "";
    }

    /**
     * 完成问题
     *
     * @param problemId
     * @param taskId
     * @param employeeVo
     * @param solveOpinion
     * @param solveVal
     * @param nodeName
     */
    private void finishProblem(String problemId, String taskId, EmployeeVo employeeVo, String solveOpinion, String solveVal, String nodeName) {
        //修改问题状态
        Problem problem = new Problem();
        problem.setProblemId(problemId);
        problem.setStatus(new Short("3"));
        tdmProblemMapper.updateByPrimaryKeySelective(problem);
        //将流程变量装进MAP中
        Map<String, Object> variable = new HashMap<>();
        variable.put(getKey(nodeName), solveVal);
        // 将流程走向下一步
        Map<String, Object> map = workFlowService.completeTask(taskId, variable, solveOpinion, employeeVo.getEmployeeId());
        if (map.get("state").toString().equals("false")) {
            new Exception(map.get("msg").toString());
        }
    }

    /**
     * 根据工单来获取审批人员信息
     *
     * @param workOrderList 工单列表
     */
    private List<String> achievePersons(List<WorkOrderVo> workOrderList) {
        List<String> names = new ArrayList<>();
        for (WorkOrderVo workOrderVo : workOrderList) {
            //查询组织下所有的人
            if (null != workOrderVo.getOrgId() && workOrderVo.getOrgId() != "") {
                List<User> list = organizationMapper.queryUsersByOrgId(workOrderVo.getOrgId());
                for (User user : list) {
                    names.add(user.getUserId());
                }
            }
            //查询工单关联的人
            if (null != workOrderVo.getUserId() && workOrderVo.getUserId() != "") {
                Employee employee = jsmEmployeeService.queryByKeyId(workOrderVo.getUserId());
                names.add(employee.getEmployeeId());
            } else {
                List<WorkOrderEmployee> userList = workOrderEmployeeMapper.selectByWorkOrderId(workOrderVo.getWorkOrderId());//查询工单关联的用户信息
                names.addAll(userList.stream().map(WorkOrderEmployee::getEmployeeId).collect(Collectors.toList()));
            }
        }
        return names;
    }

    /**
     * 根据任务信息保存工单
     *
     * @param employeeVo    登陆人信息
     * @param problemId     问题id
     * @param workOrderList 工单列表
     * @return
     */
    public void saveWorkOrderList(EmployeeVo employeeVo, String problemId, List<WorkOrderVo> workOrderList) {
        if (workOrderList != null && workOrderList.size() > 0) {
            //重要方法：给List中的元素回设置
            for (WorkOrderVo workOrder : workOrderList) {
                List<WorkOrderEmployee> userList = workOrderEmployeeMapper.selectByWorkOrderId(workOrder.getWorkOrderId());//查询工单关联的用户信息
                //重新设置主键ID
                workOrder.setWorkOrderId(UniqueUtil.uuid());
                //关键：必须拿到任务ID
                workOrder.setTaskId(problemId);
                //关键：必须拿到任务类型
                workOrder.setTaskType(new Short("5"));
                workOrder.setCreateUserId(employeeVo.getEmployeeId());
                workOrder.setModifyUserId(employeeVo.getEmployeeId());
                //工单状态：-1预处理，0创建，1作业条件检查，2作业前准备，3操作申请（关键操作--才会申请），4审核通过，5审核不通过，6已经完成，7已关闭
                workOrder.setStatus((short) 0);
                //1是删除；0是正常
                workOrder.setIsDelete((short) 0);
                //0未下载；已经下载
                workOrder.setIsDownload((short) 0);
                //0无法完成；1可以完成
                workOrder.setCanFinish((short) 1);
                //0未确认；1已经确认
                workOrder.setConfirmStatus((short) 0);
                //先保存工单
                tdmWorkOrderMapper.insertNew(workOrder);
                //保存工单和人员的关系表：
                if (null != workOrder.getUserId()) {
                    String[] array = workOrder.getUserId().split(",");
                    if (array.length > 0) {
                        for (String userId : array) {
                            if (StringUtils.isNotBlank(userId)) {
                                WorkOrderEmployee workOrderEmployee = new WorkOrderEmployee();
                                workOrderEmployee.setWorkOrderEmployeeId(UniqueUtil.uuid());
                                workOrderEmployee.setWorkOrderId(workOrder.getWorkOrderId());
                                workOrderEmployee.setEmployeeId(userId);
                                workOrderEmployeeMapper.insert(workOrderEmployee);
                            }
                        }
                    }
                } else if (null != userList && userList.size() > 0) {
                    for (WorkOrderEmployee workOrderEmployee : userList) {
                        WorkOrderEmployee employee = new WorkOrderEmployee();
                        employee.setWorkOrderEmployeeId(UniqueUtil.uuid());
                        employee.setWorkOrderId(workOrder.getWorkOrderId());
                        employee.setEmployeeId(workOrderEmployee.getEmployeeId());
                        workOrderEmployeeMapper.insert(employee);
                    }
                }
                //保存自定义巡检
                if (null != workOrder.getRemark() && workOrder.getRemark() != "") {
                    JSONArray jsonArray = JSON.parseArray(workOrder.getRemark());
                    List<CustomWorkCriteria> list = new ArrayList<>();
                    for (Object o : jsonArray) {
                        JSONObject jsonObject = JSON.parseObject(o.toString());
                        CustomWorkCriteria customWorkCriteria = new CustomWorkCriteria();
                        customWorkCriteria.setId(UniqueUtil.uuid());
                        customWorkCriteria.setWorkOrderId(workOrder.getWorkOrderId());
                        customWorkCriteria.setWorkInstanceId(jsonObject.get("workInstanceId").toString());
                        customWorkCriteria.setRankId(Integer.parseInt(jsonObject.get("categoryIndex").toString()));
                        customWorkCriteria.setCategory(jsonObject.get("category").toString());
                        list.add(customWorkCriteria);
                    }
                    if (list != null && list.size() > 0) {
                        customWorkCriteriaMapper.insertByList(list);
                    }
                }
            }
        }
    }

    /**
     * 查询历史审批记录
     *
     * @param businessId 业务id
     */
    @Override
    public List<HistoricNode> queryApprovalRecords(String businessId) {
        return tdmProblemMapper.queryApprovalRecords(businessId);
    }
}
